home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DDJMAG / DDJ9310.ZIP / DFPP03.ZIP / MOUSE.CPP < prev    next >
C/C++ Source or Header  |  1993-09-24  |  5KB  |  222 lines

  1. // ------------- mouse.cpp
  2.  
  3. #include <stdio.h>
  4. #include "desktop.h"
  5.  
  6. // -------- mouse constructor
  7. Mouse::Mouse()
  8. {
  9.     // ------- see if mouse driver is installed
  10.     int far *ms42 = (int far *) MK_FP(0, MOUSE*4+2);
  11.     int far *ms4  = (int far *) MK_FP(0, MOUSE*4);
  12.     unsigned char far *ms = (unsigned char far *) MK_FP(*ms42, *ms4);
  13.     // --- if the interrupt vector is null or points to a retf,
  14.     //     the mouse driver is not installed
  15.     installed = (Bool) (ms != 0 && *ms != 0xcf);
  16.  
  17.     if (installed)    {
  18.         // --- get the mouse state buffer size
  19.         CallMouse(BUFFSIZE);
  20.         statebuffer = new char[regs.x.bx];
  21.         // --- save the mouse state
  22.         CallMouse(SAVESTATE, 0, 0,
  23.             FP_OFF(statebuffer), FP_SEG(statebuffer));
  24.         // --- reset the mouse
  25.         CallMouse(RESETMOUSE);
  26.         prevx = prevy =
  27.         clickx = clicky =
  28.         releasex = releasey -1;
  29.         SetTravel(0, desktop.screen().Width()-1, 0,
  30.                                 desktop.screen().Height()-1);
  31.     }
  32. }
  33.  
  34. Mouse::~Mouse()
  35. {
  36.     if (installed)    {
  37.         Hide();
  38.         // --- restore the mouse state
  39.         CallMouse(RESTORESTATE, 0, 0,
  40.             FP_OFF(statebuffer), FP_SEG(statebuffer));
  41.         delete [] statebuffer;
  42.     }
  43. }
  44.  
  45. void Mouse::GetPosition(int &mx, int &my)
  46. {
  47.     mx = my = 0;
  48.     if (installed)    {
  49.         CallMouse(READMOUSE);
  50.         mx = regs.x.cx/8;
  51.         my = regs.x.dx/8;
  52.         if (desktop.screen().Width() == 40)
  53.             mx /= 2;
  54.     }
  55. }
  56.  
  57. void Mouse::SetPosition(int x, int y)
  58. {
  59.     if (installed)    {
  60.         if (desktop.screen().Width() == 40)
  61.             x *= 2;
  62.         CallMouse(SETPOSITION,0,x*8,y*8);
  63.     }
  64. }
  65.  
  66. Bool Mouse::Moved()
  67. {
  68.     int x, y;
  69.     Bool rtn = False;
  70.     if (installed)    {
  71.         GetPosition(x, y);
  72.         rtn = (Bool) (x != prevx || y != prevy);
  73.         prevx = x;
  74.         prevy = y;
  75.     }
  76.     return rtn;
  77. }
  78.  
  79. void Mouse::Show()
  80. {
  81.     if (installed)
  82.         CallMouse(SHOWMOUSE);
  83. }
  84.  
  85. void Mouse::Hide()
  86. {
  87.     if (installed)
  88.         CallMouse(HIDEMOUSE);
  89. }
  90.  
  91. Bool Mouse::LeftButton()
  92. {
  93.     Bool rtn = False;
  94.     if (installed)    {
  95.         CallMouse(READMOUSE);
  96.         rtn = (Bool) ((regs.x.bx & 1) == 1);
  97.     }
  98.     return rtn;
  99. }
  100.  
  101. Bool Mouse::ButtonReleased()
  102. {
  103.     Bool rtn = False;
  104.     if (installed)    {
  105.         CallMouse(BUTTONRELEASED);
  106.         rtn = (Bool) (regs.x.bx != 0);
  107.     }
  108.     return rtn;
  109. }
  110.  
  111. void Mouse::SetTravel(int minx, int maxx, int miny, int maxy)
  112. {
  113.     if (installed)    {
  114.         if (desktop.screen().Width() == 40)    {
  115.             minx *= 2;
  116.             maxx *= 2;
  117.         }
  118.         CallMouse(XLIMIT, 0, minx*8, maxx*8);
  119.         CallMouse(YLIMIT, 0, miny*8, maxy*8);
  120.     }
  121. }
  122.  
  123. void Mouse::CallMouse(int m1,int m2,int m3,int m4, unsigned es)
  124. {
  125.     struct SREGS sregs;
  126.     segread(&sregs);
  127.     if (es != 0)
  128.         sregs.es = es;
  129.     regs.x.dx = m4;
  130.     regs.x.cx = m3;
  131.     regs.x.bx = m2;
  132.     regs.x.ax = m1;
  133.     int86x(MOUSE, ®s, ®s, &sregs);
  134. }
  135.  
  136. // ------ get the window to send mouse events
  137. DFWindow *Mouse::MouseWindow(int mx, int my)
  138. {
  139.     DFWindow *Mwnd = desktop.inWindow(mx, my);
  140.     if (Mwnd == 0)
  141.         Mwnd = desktop.FocusCapture();
  142.     else if (desktop.FocusCapture() != 0)
  143.         if (!Mwnd->isDescendedFrom(desktop.FocusCapture()))
  144.             Mwnd = desktop.FocusCapture();
  145.     return Mwnd;
  146. }
  147.  
  148. void Mouse::DispatchRelease()
  149. {
  150.     if (ButtonReleased())    {
  151.         int mx, my;
  152.         GetPosition(mx, my);
  153.         DFWindow *Mwnd;
  154.         if ((Mwnd = MouseWindow(mx, my)) == 0)
  155.             return;
  156.         // ------- disable typematic check
  157.         clickx = clicky = -1;
  158.         delaytimer.DisableTimer();
  159.         // ------- the button was released
  160.         if (mx == releasex && my == releasey)
  161.             // ---- same position as last left button release
  162.             if (doubletimer.TimerRunning())
  163.                 // -- second click before double timeout
  164.                 Mwnd->DoubleClick(mx, my);
  165.         doubletimer.SetTimer(DOUBLETICKS);
  166.         Mwnd->ButtonReleased(mx, my);
  167.         releasex = mx;
  168.         releasey = my;
  169.     }
  170. }
  171.  
  172. void Mouse::DispatchMove()
  173. {
  174.     if (Moved())    {
  175.         int mx, my;
  176.         GetPosition(mx, my);
  177.         DFWindow *Mwnd;
  178.         if ((Mwnd = MouseWindow(mx, my)) != 0)    {
  179.             Mwnd->MouseMoved(mx, my);
  180.             clickx = clicky = -1;
  181.         }
  182.     }
  183. }
  184.  
  185. void Mouse::DispatchLeftButton()
  186. {
  187.     if (LeftButton())    {
  188.         int mx, my;
  189.         GetPosition(mx, my);
  190.         DFWindow *Mwnd;
  191.         if ((Mwnd = MouseWindow(mx, my)) == 0)
  192.             return;
  193.         if (mx == clickx && my == clicky)    {
  194.             if (delaytimer.TimedOut())    {
  195.                 // ---- button held down a while
  196.                 delaytimer.SetTimer(DELAYTICKS);
  197.                 // ---- post a typematic-like button
  198.                 Mwnd->LeftButton(mx, my);
  199.             }
  200.         }
  201.         else    {
  202.             // --------- new button press
  203.             delaytimer.SetTimer(FIRSTDELAY);
  204.             if (Mwnd->SetFocus())
  205.                 Mwnd->LeftButton(mx, my);
  206.             clickx = mx;
  207.             clicky = my;
  208.         }
  209.     }
  210. }
  211.  
  212. // -------- dispatch mouse events
  213. void Mouse::DispatchEvent()
  214. {
  215.     DispatchRelease();
  216.     DispatchMove();
  217.     DispatchLeftButton();
  218. }
  219.  
  220.  
  221.  
  222.